import torch
import torch.nn as nn
class SimpleNN(nn.Module):
    def __init__(self):
        super(SimpleNN,self).__init__()
        self.fc1=nn.Linear(2,2)
        self.fc2=nn.Linear(2,1)
    def forward(self,x):
        x=torch.relu(self.fc1(x))
        x=self.fc2(x)
        return x
model=SimpleNN()
print(model)

#连接层
"""
nn.Linear(in_features,out_features)全连接层，输入in_features个特征，输出out_features个特征
nn.Conv2d(in_channels,out_channels,kernel_size)2D卷积层，用于图像处理
nn.MaxPool2d(kernel_size)2D池化层，用于降维
nn.ReLU():RELU激活函数，常用于隐藏层
nn.Softmax(dim)：Softmax激活函数，通常用于输出层，适用于多类分类问题
"""

#激活函数
'''
import torch.nn.functional as F
output=F.relu(input_tensor)#定义为f(x)=max(0,x),有助于解决梯队消失
output=torch.sigmoid(input_tensor)#用于二分类问题，输出值在0-1之间
output=torch.tanh(input_tensor)#输出值在-1到1之间
'''

#损失函数
criterion=nn.MSELoss()#均方误差，回归问题常用，计算输出和目标值的平方差
criterion=nn.CrossEntropyLoss()#交叉熵损失，计算输出和而真实标签之间的交叉熵
criterion=nn.BCEWithLogitsLoss()#二分类交叉熵损失，二分类问题结合了Sigmoid激活和二元交叉熵损失。

#优化器
import torch.optim as optim
optimizer=optim.SGD(model.parameters(),lr=0.01)#使用SGD优化器，随机梯队下降
optimizer=optim.Adam(model.parameters(),lr=0.001)#使用Adam优化，自适应矩估计
#RMSprop#均方根传播

#训练过程
X= torch.randn(10,2)
Y=torch.randn(10,1)
for epoch in range(100):
    model.train()
    optimizer.zero_grad()
    output=model(X)
    loss=criterion(output,Y)
    loss.backward()#反向传播
    optimizer.step()#更新权重
    if (epoch + 1)%10==0: #每10轮输出一次损失
        print(f"Epoch=[{epoch+1}/100],loss:{loss.item():.4f}")

#测试与评估
X_test=torch.randn(10,2)
Y_test=torch.randn(10,1)
model.eval()
with torch.no_grad():
    output=model(X_test)
    loss=criterion(output,Y_test)
    print(f'Test LOSS:{loss:.4f}')



